package product

import (
	"context"
	"encoding/json"
	"fmt"
	"strings"

	"mall/common/globalkey"
	"mall/common/moneyx"
	"mall/common/mqueuex"
	"mall/common/resultx"
	"mall/common/utils/pointy"
	"mall/service/product/model"
	"mall/service/product/rpc/internal/svc"
	"mall/service/product/rpc/types/product"

	"github.com/zeromicro/go-zero/core/logx"
)

type ExchangeProductLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewExchangeProductLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ExchangeProductLogic {
	return &ExchangeProductLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *ExchangeProductLogic) ExchangeProduct(in *product.ExchangeProductReq) (*product.BaseResp, error) {
	if in.ProductId == nil || *in.ProductId == 0 {
		return nil, resultx.StatusError(resultx.PRODUCT_ID_REQUIRED, "")
	}

	if in.SkuId == nil || *in.SkuId == 0 {
		return nil, resultx.StatusError(resultx.PRODUCT_VARIATION_ID_REQUIRED, "")
	}

	if in.UserId == nil || *in.UserId == 0 {
		return nil, resultx.StatusError(resultx.USER_ID_REQUIRED, "")
	}

	userId := *in.UserId

	goods, err := l.svcCtx.CurrentProduct.FindOne(l.ctx, *in.ProductId)
	if err != nil {
		return nil, resultx.StatusError(resultx.DB_ERROR, "")
	}

	if goods.Status != uint16(globalkey.StatusEnabled) {
		return nil, resultx.StatusError(resultx.PRODUCT_ID_INVALID, "")
	}

	filterMap := make(map[string]map[string][]any)
	filterMap[model.ProductVariationColumns.ProductID] = map[string][]any{
		"equalTo": {*in.ProductId},
	}
	filterMap[model.ProductVariationColumns.ProductVariationID] = map[string][]any{
		"equalTo": {*in.SkuId},
	}
	list, _, err := l.svcCtx.CurrentProduct.GetVariationList(l.ctx, model.M{
		"pageSize": uint64(1),
	}, -1, filterMap)
	if err != nil {
		return nil, resultx.StatusError(resultx.DB_ERROR, "")
	}

	if len(list) > 0 {
		product := list[0]
		if product.GemPrice > 0 {
			skuMetaFilterMap := make(map[string]map[string][]any)
			skuMetaFilterMap[model.ProductVariationMetumColumns.ProductID] = map[string][]any{
				"equalTo": {product.ProductVariationID},
			}
			skuMetaFilterMap[model.ProductVariationMetumColumns.MetaKey] = map[string][]any{
				"equalTo": {"_sku"},
			}
			skuMetaList, _, err := l.svcCtx.CurrentProduct.GetVariationMeta(l.ctx, model.M{}, -1, skuMetaFilterMap)
			if err != nil {
				return nil, resultx.StatusError(resultx.DB_ERROR, "")
			}

			var sku string
			if len(skuMetaList) > 0 {
				for _, v := range skuMetaList {
					key := strings.TrimSpace(v.MetaKey)
					if len(key) > 0 && v.MetaValue.Valid {
						val := v.MetaValue.String
						switch key {
						case "_sku": // 1-净含量-Net volume:0-10ml-  属性及其值
							sku = val
						}
					}
				}
			}

			data := &mqueuex.ProductInfo{
				UserId:      userId,
				ProductId:   goods.ID,
				ProductName: goods.Title,
				ProductCode: goods.ProductCode,
				SkuId:       product.ProductVariationID,
				SkuCode:     product.SkuCode,
				Sku:         sku,
				Point:       pointy.GetPointer(moneyx.FormatGem(int64(product.GemPrice))),
			}

			str, err := json.Marshal(data)
			if err != nil {
				return nil, fmt.Errorf("ExchangeProduct json.Marshal error: %+v", err)
			}

			m := mqueuex.DistributePointsMessage{
				UserId:     pointy.GetPointer(userId),
				SourceType: pointy.GetPointer(globalkey.UserAssetSourceTypeProduct),
				Product:    pointy.GetPointer(string(str)),
			}
			body, err := json.Marshal(m)
			if err != nil {
				return nil, fmt.Errorf("ExchangeProduct json.Marshal error: %+v", err)
			}

			err = l.svcCtx.KqDistributePointsClient.Push(string(body))
			if err != nil {
				return nil, fmt.Errorf("ReceiveCoupon deductPoint error: %+v", err)
			}
		}
	}

	return &product.BaseResp{}, nil
}
